﻿using System;
using System.Linq;
using System.Threading;
using AOPDemo.Aspects;
using AOPDemo.Data;
using AOPDemo.Interfaces;
using AOPDemo.Messages;

namespace AOPDemo.Services
{
    [LogExecutionTime]
    [LogErrors]
    [Audit]
    public class BankingService : IBankingService
    {
        private readonly Accounts accounts = new Accounts();
        private readonly Transactions transactions = new Transactions();

        #region Implementation of IBankingService
        [CachedMember]
        public GetAccountsResponse GetAccounts(GetAccountsRequest request)
        {
            Thread.Sleep(1000); // Simulate some latency
            return new GetAccountsResponse
                       {
                           Success = true,
                           Accounts = accounts[request.AuthToken.UserId]
                       };
        }
        [CachedMember]
        public SearchTransactionsResponse SearchTransactions(SearchTransactionsRequest request)
        {
            Thread.Sleep(1000); // Simulate some latency
            int startIndex = (request.PagingContext.Page - 1)*request.PagingContext.PageSize;
            return new SearchTransactionsResponse
                       {
                           Success = true,
                           Transactions =
                               transactions[request.AccountId].Skip(startIndex).Take(request.PagingContext.PageSize).
                               ToList()
                       };
        }

        public TransferResponse Transfer(TransferRequest request)
        {
            Thread.Sleep(1000); // Simulate some latency
            decimal balance =
                accounts[request.AuthToken.UserId].First(account => account.Id.Equals(request.FromAccountId)).Balance;
            if (request.Amount > balance)
               throw new ApplicationException(string.Format("You don't have enough funds to complete this transfer! You requested {0}, but you only have {1}.", request.Amount, balance));

            return new TransferResponse();
        }

        #endregion
    }
}